package com.yanhui.api.ai;

import com.hankcs.hanlp.HanLP;
import com.hankcs.hanlp.corpus.occurrence.Occurrence;
import com.hankcs.hanlp.corpus.occurrence.PairFrequency;
import com.hankcs.hanlp.corpus.occurrence.TermFrequency;
import com.hankcs.hanlp.corpus.occurrence.TriaFrequency;
import com.hankcs.hanlp.dictionary.CoreSynonymDictionary;
import com.hankcs.hanlp.model.crf.CRFLexicalAnalyzer;
import com.yanhui.modal.ai.SignEntity;
import com.yanhui.utils.file.word.ComputeTfIdf;
import com.yanhui.utils.http._cmsUtils;
import com.yanhui.utils.http._httpUtils;
import com.yanhui.utils.string._stringUtils;
import net.sf.json.JSONObject;
import org.wltea.analyzer.core.IKSegmenter;
import org.wltea.analyzer.core.Lexeme;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.StringReader;
import java.net.URLEncoder;
import java.util.*;

/**
 * 自然语言ai
 */
public class NaturalLanguageApi {

    /**
     * 分词接口 提供智能分词功能，支持基础词与混排词粒度两种粒度，其中基础词粒度最小，适合搜索场景，而混合词粒度倾向于保留更多的短语词。
     *
     * @param text
     * @return data
     * @throws Exception
     */
    public static String getParticiple(String text) throws Exception {
        SignEntity signEntity = new SignEntity(text,2);
        String url = "https://api.ai.qq.com/fcgi-bin/nlp/nlp_wordseg?app_id=" + signEntity.getApp_id() + "&time_stamp="
                + signEntity.getTime_stamp() + "&nonce_str=" + signEntity.getNonce_str() + "&sign="
                + signEntity.getSign() + "&text=" + URLEncoder.encode(text.trim(), "GBK");
        String message = _cmsUtils.doHttpGet(url,"GBK");
        JSONObject demoJson = JSONObject.fromObject(message);
        String data = demoJson.getString("data");
        return data;
    }

    /**
     * 专有名词识别接口 在分词接口的基础上，增加专有名词识别能力，可以帮您轻松找出一段文本中的专有名词。
     *
     * @param text
     * @return data 专有名词编码 专有名词名称 1000 人名 1100 地名 1200 机构名 1300 时间
     * @throws Exception
     */
    public static String getProperNouns(String text) throws Exception {
        SignEntity signEntity = new SignEntity(text,2);
        String url = "https://api.ai.qq.com/fcgi-bin/nlp/nlp_wordner?app_id=" + signEntity.getApp_id() + "&time_stamp="
                + signEntity.getTime_stamp() + "&nonce_str=" + signEntity.getNonce_str() + "&sign="
                + signEntity.getSign() + "&text=" + URLEncoder.encode(text.trim(), "GBK");
        String message = _cmsUtils.doHttpGet(url,"GBK");
        System.out.println(message);
        JSONObject demoJson = JSONObject.fromObject(message);
        String data = demoJson.getString("data");
        return data;
    }

    /**
     * CRF分词
     * @param tests
     * @return
     * @throws IOException
     */
    public static String getCRFAnalyzer(String[] tests) throws IOException {
        String result = "";
        CRFLexicalAnalyzer analyzer = new CRFLexicalAnalyzer();
        for (String sentence : tests)
        {
            result += analyzer.analyze(sentence);
//            System.out.println(analyzer.seg(sentence));
        }
        return result;
    }

    /**
     * 关键词提取
     * @param content
     * @return
     */
    public static List<String> getKeyword(String content){
        return HanLP.extractKeyword(content, 5);
    }

    /**
     * 自动摘要
     * @param content
     * @return
     */
    public static List<String> getSummary(String content){
        return HanLP.extractSummary(content, 3);
    }

    /**
     * 短语提取
     * @param content
     * @return
     */
    public static List<String> getPhrase(String content){
        return HanLP.extractPhrase(content, 10);
    }

    /**
     * 一键重写
     * @param content
     * @return
     */
    public static String getRewrite(String content){
        return CoreSynonymDictionary.rewrite(content);
    }

    /**
     * 词语频繁出现
     * @param content
     * @return
     */
    public static void getOccurrence(String content){
        Occurrence occurrence = new Occurrence();
        occurrence.addAll(content);
        occurrence.compute();

        Set<Map.Entry<String, TermFrequency>> uniGram = occurrence.getUniGram();
        for (Map.Entry<String, TermFrequency> entry : uniGram)
        {
            TermFrequency termFrequency = entry.getValue();
            System.out.println(termFrequency);
        }

        Set<Map.Entry<String, PairFrequency>> biGram = occurrence.getBiGram();
        for (Map.Entry<String, PairFrequency> entry : biGram)
        {
            PairFrequency pairFrequency = entry.getValue();
            if (pairFrequency.isRight())
                System.out.println(pairFrequency);
        }

        Set<Map.Entry<String, TriaFrequency>> triGram = occurrence.getTriGram();
        for (Map.Entry<String, TriaFrequency> entry : triGram)
        {
            TriaFrequency triaFrequency = entry.getValue();
            if (triaFrequency.isRight())
                System.out.println(triaFrequency);
        }
    }


    public static void main(String[] args) throws Exception {
        /*String text = "一起艳学天气微服务（四）——API网关";
        String a = NaturalLanguageApi.getParticiple(text);
        a = a.substring(a.indexOf("\"base_tokens\":["),a.indexOf("\"mix_tokens\""));
        System.out.println(a);
        String title = "keyword";
        String pat = "\"word\":\"(.+?)\",\"offset\"";
        List<String> list = _pachongUtils.getCode(a, title, pat);
        for(String str: list){
            System.out.println(str);
        }*/

//        String content = "虽然有不少人可能是因为不忍心看下去而离场，但这部作品离处处是无法忽视的天才手笔，从台词到节奏都给人无与伦比的体验，笑到腹痛，又残忍到全场倒抽一口冷气。LVT注定是影史上炸裂的一笔。";
//        String a = getArticle(content);
//        System.out.println(a);
//
//        String a1= "Steel";
//        String b = "Steel Pipe";
//        System.out.println("相似度："+getSimilarityRatio(a1,b));

//        getIkanalyzer("d");
        getTFIDF();
    }

    /**
     * 伪原创
     * 奶盘网www.naipan.com
     * 时间间隔10分钟以上
     * @param content
     * @return
     */
    public static String getArticle(String content){
                String url = "http://www.naipan.com/open/weiyuanchuang/towei.html";// 奶盘请求接口地址
                Map params = new HashMap();// 请求参数
                params.put("regname", "test@163.com");// 授权用户
                params.put("regsn", "ICQl3kdebh7zns97XVT9dLDBASR7pBrM2AAKbI7HpMw=");// 授权码
                params.put("content", content);// 文章内容
                String returnContent = "";
                JSONObject result=null;
                try {
                    returnContent = _httpUtils.net(url, params, "POST");
                    result=JSONObject.fromObject(returnContent);
                    //System.out.println(returnContent);// 返回json格式，如{"content":"文章内容","message":"伪原创成功！","result":1}
                } catch (Exception e) {
                    e.printStackTrace();
                }
             return result.toString();
    }

    /**
     * 两文本相似度
     * @return
     */
    public static String getSimilarityRatio(String text1, String text2){
        return _stringUtils.getSimilarityRatio(text1, text2)*100+"%";
    }

    public static List<String> getIkanalyzer (String text) {
        List<String> result = new ArrayList<String>();
            StringReader re = new StringReader(text);
            IKSegmenter ik = new IKSegmenter(re, true);
            Lexeme lex = null;
            try {
                while ((lex = ik.next()) != null) {
                    result.add(lex.getLexemeText());
                }
            } catch (Exception e) {
            }
            return result;
    }


    /**
     * 文本分词后利用tfidf算法计算每个文档的tfidf值，以便后期跑实验使用
     * 1.读取文件夹下的文档并分词
     *
     * ReadFiles类的使用
     *
     * readFile方法：读取所有文件夹下的文件路径，返回一个list文件路径列表
     * readContent方法：将一个文档中的所有内容读成一个字符串，返回一个string文档内容
     * readFileAllContent方法：将所有文档中的内容读到一起，返回一个map，key是文档名，value是文档内容
     * cutWordtoMap方法：将每个文档中内容分词，返回一个map，key是文档名，value是分完词后的内容，是一个字符串，单词以空格分割。
     * 注：分词软件，张华平分词软件:
     *
     * 2.读取分完词的文档并计算每个文档的单词tfidf的值
     *
     * Tfidf类的使用
     *
     *     该类中定义了两个静态变量：一个是文档索引一个是单词索引
     *     static Map<String, Integer> docIndex=new HashMap<String, Integer>();
     *     static Map<String, Integer> wordIndex=new LinkedHashMap<String, Integer>();
     *
     * saveIndex方法：String wordfile,String docfile,Map<String,String> doc_words三个参数，该方法将步骤1中分完词的map传进来，处理成文档索引和单词索引并保存到文件中。
     *
     * tfCalculate方法：String wordAll参数是分完词的文档内容，计算每个文档中单词的tf值，并返回一个map，key是单词，value是单词tf值
     *
     * tfidfCalculate方法：int D, Map<String,String> doc_words,Map<String,Float> tf三个参数，D是所有文档的数量，doc_words是步骤1中分完词的map，tf是单个文档的单词的tf值。
     *
     * 3.程序主类
     *
     * ComputeTfIdf类的使用
     *
     *     3.1首先创建一个ReadFiles对象，将文件读到map，对应的是（文档名，文档内容）Map<String,String> doc_content=rf.readFileAllContent(filepath);
     *     3.2分词 Map<String,String> doc_words=rf.cutWordtoMap((HashMap<String, String>) doc_content);计算总文档数量int D=doc_words.keySet().size();
     *     3.3调用saveIndex方法,创建文档索引和单词索引，然后保存文档索引和单词索引到文件 Tfidf.saveIndex(wordfile, docfile, doc_words);
     *     3.4计算每个文档的单词的tfidf值并保存到文本
     * 4.主程序入口
     *
     * Test类main方法
     *
     * String filepath="";//定义文档的文件路径，是一个文件夹
     * String outputPath="";//定义输出文件
     * String docfile="";//定义文档索引输出路径
     * String wordfile="";//定义单词索引输出路径
     * ComputeTfIdf.compute(filepath, outputPath, docfile, wordfile);
     * @throws FileNotFoundException
     * @throws IOException
     */
    public static void getTFIDF() throws FileNotFoundException, IOException {

        //直接使用compute计算
        String filepath="c:/yhfile/textFile";
        String outputPath="c:/yhfile/textOutFile.txt";
        String docfile="c:/yhfile/indexDocFile/1.txt";
        String wordfile="c:/yhfile/indexWordFile/1.txt";
        ComputeTfIdf.compute(filepath, outputPath, docfile, wordfile);
    }




}
